#ifndef _ZQ_GL_H_
#define _ZQ_GL_H_

#ifdef __cplusplus
extern "C" {
#endif
#ifdef ZQ_SIMULATOR
#include "simu_800.h"
#endif
#include "ql_fs.h"
#include "ql_api_osi.h"
#include "ql_log.h"
#include "ql_api_sim.h"
#include "ql_api_dev.h"
#include "ql_api_datacall.h"
#include "ql_api_rtc.h"
#include "ql_http_client.h"
#include "ql_power.h"
#include "ql_api_nw.h"

#include "cJSON.h"
#include "kg_json.h"
//#include "../../../../share/share.h"
#include "predef.h"
#include "share.h"

#define KG_PRJ_AKM

#define ZQ_APN_ABROAD			0



// OTA服务器地址
#define ZQ_FOTA_URL "http://iot_2023.origin-tech.cn:9945/api/device/version/dtu"    	// 正式服务器
// #define ZQ_FOTA_URL "http://ota.origin-tech.cn:9944/api/device/version/dtu"           // OTA测试服务器
// MQTT服务器地址
// #define IOT_MQTT_HOST "mqtt://emqtt-test.yunext.com:18861"                           // AKM客户测试服务器
#define IOT_MQTT_HOST "mqtt://mqtt.aucmace.com:1883"                                    // AKM客户正式服务器
// #define IOT_MQTT_HOST "mqtt://iot_yk.origine-tech.cn:1883"                            // 自研MQTT服务器
// #define IOT_MQTT_HOST "iot-as-mqtt.cn-shanghai.aliyuncs.com"                             /* 阿里云平台上海站点的域名后缀 */

//  general function return value -----------------------------------------------------------------------------------------------    
typedef enum {
	ZQ_RET_OK = 0,
	ZQ_RET_ERR = -1,
	ZQ_RET_MEM_ERR = -2,
	ZQ_RET_FILE_ERR = -3,
	ZQ_RET_TRYMAX_ERR = -4,
	ZQ_RET_OVERTIME_ERR = -5,
} ZQ_RET_CODE;

// LOG/Debug Macro -----------------------------------------------------------------------------------------------

// general function error log
#define ZQ_LOG_FAILED(func_name, err) ZQLOG("@err@: func-%s failed: %d", #func_name, (int)err)

//  -----------------------------------------------------------------------------------------------
// translate IMEI string to virtual mac address string
#define ZQ_IMEI2MAC(mac, imei) sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X",					\
	(((imei[3]&0xf)<<4)|(imei[4]&0xf))^0xff, (((imei[5]&0xf)<<4)|(imei[6]&0xf))^0xff, 			\
	(((imei[7]&0xf)<<4)|(imei[8]&0xf))^0xff, (((imei[9]&0xf)<<4)|(imei[10]&0xf))^0xff, 			\
	(((imei[11]&0xf)<<4)|(imei[12]&0xf))^0xff, (uint8_t)(((((imei[13]&0xf)<<4)|(imei[14]&0xf))^0xff) + 1)) 	

// static parameters definition -----------------------------------------------------------------------------------------------
#define IMEI_MAX 16
#define IMSI_MAX 16
#define ICCID_MAX 24
#define MAC_MAX 18

#define ZQ_SIM_0 			(0)
#define ZQ_PROFILE_IDX		(1)
#define ZQ_APN_NAME			("CMIOT")

#define ZQ_SWAP(a,b)  {(a)=(a)^(b);(b)=(a)^(b);(a)=(a)^(b);}	// 交换两个数
#define ZQ_SWAP_P(a,b)  {(a)=(void*)(((size_t)(a))^((size_t)(b)));(b)=(void*)(((size_t)(a))^((size_t)(b)));(a)=(void*)(((size_t)(a))^((size_t)(b)));} // 交换两个指针

// #define ZQ_UPLOAD_PERIOD_S	(300) //1800 miniutes period for uploadcollect #Conan?

typedef struct {
	uint32_t id;
	uint32_t param1;
	size_t param2;
} ZyMessage;
typedef struct {
	int max_cnt;		// 最大记录条数
	// int rec_size;	// 记录的最大size
	int cnt;			// 实际有多少条记录
	int pos;			// 指向第一条记录存放起始位置
	ql_mutex_t self_mutex;
	void* buffs[0];		// Circular Stack 记录数组地址
} ZyQueue;

typedef void * zq_StackHandle;

extern unsigned int ZqGetLocalStample(void);
extern unsigned int ZqGetUTCStample(void);
extern void ZqSetUTCStample(unsigned int sec);
extern void ZqGetRTC_yyyyMMddHHmmss(char* buf);

extern int zq_EasyIsFileExisted(const char *path);
extern int zq_EasyFileRead(char *path, void *buf, int size);
extern int zq_EasyFileWrite(char *path, void *buf, int size);
extern int zq_EasyMkDir(const char *path);
extern int zq_StartDataCall(void);
extern int zq_StackCreate(zq_StackHandle *psh, int max_cnt);
extern void *zq_StackPush(zq_StackHandle psh, void *pRec);
extern void *zq_StackPop(zq_StackHandle psh);
extern int zq_StackGetCount(zq_StackHandle *psh);

extern ZyQueue* ZyCreateMsgQueue(int max_cnt);
extern void* ZyPostMsg(ZyQueue* pQueue, void* msg);
extern void* zq_GetMsg(ZyQueue* pQueue);

extern int zq_GetTimeSpan(void);
#define ZQ_TIME_SPAN1    do{            \
    ZQLOG("Begin Time Span Test...");  \
    zq_GetTimeSpan(); } while(0)       
#define ZQ_TIME_SPAN2   ZQLOG("End Time Span Test, span = %d ms", zq_GetTimeSpan())


#define ZQ_OFFLINE_PKG_SIZE     100     // 每个pkg file存最多100条msg
#define ZQ_OFFLINE_MSG_SIZE		1024	// 每个msg（含\0） 小于 1024
typedef struct {
	int max_cnt;	    // 记录的实际最大条数
	int cnt;			// 实际有多少条记录，由于pkg的存在，可能会比真实的max_cnt大
	int pos;			// 指向下一个新记录存放位置
	char dir[0];		// 记录文件所在的目录，注意，目录完全由fifo程序掌控，不能存在任何其他文件。
}ZqCircularFifo;

extern ZqCircularFifo* ZqFifoCreate(const char* path, int max_cnt);
extern int ZqFifoAdd(ZqCircularFifo* pf, const char* msg);
extern int ZqFifoGetMsgCnt(ZqCircularFifo* pf);
extern int ZqFifoGet(ZqCircularFifo* pf, char* msg_buf, int msg_buf_size, int msg_cnt);
extern int ZqFifoRemove(ZqCircularFifo* pf, int msg_cnt);

#ifdef __cplusplus
} /*"C" */
#endif

#endif
